﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;

namespace BITUI.Audio
{
    class AudioDataConverter
    {
        //從指定音源中讀取 44100 *2 *float的PCM數據，自動轉換
        public static int ReadFloat_44100_2(IAudioData src, float[] data, int offset, int count)
        {
            if (src.Channel == 2 && src.Freq == 44100)//輸出一致，無須轉換
            {
                return src.ReadFloat(data, offset, count);
            }
            if (src.Freq == 22050)//對這兩個整數倍頻率,可以優化
            {
                return Convert_22050(src, data, offset, count);
            }
            else if (src.Freq == 11025)//對這兩個整數倍頻率,可以優化
            {
                return Convert_11025(src, data, offset, count);
            }
            else
            {
                //不含插值，生硬的index縮放，音質肯定會有一點失真，所以 你最好采用 44100 22050 11025 的音源
                return Convert_Any(src, data, offset, count);
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static int Convert_Any(IAudioData src, float[] data, int offset, int count)
        {
            int samplecount = count / 2;

            float scale = 44100.0f / src.Freq;

            int srcsamplecount = (int)(samplecount / scale);



            var buf = new float[srcsamplecount * src.Channel];

            int srcsamplecountread = src.ReadFloat(buf, 0, buf.Length) / src.Channel;
            int samplecountread = (int)(srcsamplecountread * scale);

            for (var cursindex = 0; cursindex < samplecountread; cursindex++)
            {
                //從cursindex->srcsindex的轉換是不同
                var srcsindex = (int)(cursindex / scale);

                var left = srcsindex * src.Channel;
                var right = left + 1 % src.Channel;
                data[offset + cursindex * 2] = buf[left];
                data[offset + cursindex * 2 + 1] = buf[right];
            }
            return samplecountread * 2;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static int Convert_22050(IAudioData src, float[] data, int offset, int count)
        {
            int samplecount = count / 2;

            const int scale = 2;

            int srcsamplecount = (int)(samplecount / scale);



            var buf = new float[srcsamplecount * src.Channel];

            int srcsamplecountread = src.ReadFloat(buf, 0, buf.Length) / src.Channel;
            int samplecountread = (int)(srcsamplecountread * scale);

            for (var cursindex = 0; cursindex < samplecountread; cursindex++)
            {
                //從cursindex->srcsindex的轉換是不同
                var srcsindex = (int)(cursindex / scale);

                var left = srcsindex * src.Channel;
                var right = left + 1 % src.Channel;
                data[offset + cursindex * 2] = buf[left];
                data[offset + cursindex * 2 + 1] = buf[right];
            }
            return samplecountread * 2;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static int Convert_11025(IAudioData src, float[] data, int offset, int count)
        {
            int samplecount = count / 2;

            const int scale = 4;

            int srcsamplecount = (int)(samplecount / scale);



            var buf = new float[srcsamplecount * src.Channel];

            int srcsamplecountread = src.ReadFloat(buf, 0, buf.Length) / src.Channel;
            int samplecountread = (int)(srcsamplecountread * scale);

            for (var cursindex = 0; cursindex < samplecountread; cursindex++)
            {
                //從cursindex->srcsindex的轉換是不同
                var srcsindex = (int)(cursindex / scale);

                var left = srcsindex * src.Channel;
                var right = left + 1 % src.Channel;
                data[offset + cursindex * 2] = buf[left];
                data[offset + cursindex * 2 + 1] = buf[right];
            }
            return samplecountread * 2;
        }
    }
}
